﻿namespace FlexPlatform.DataModel.Validation.Generic_ValidationRules
{
    using System;
    using System.Collections.Generic;

    using FlexPlatform.BusinessLogic.Validation;
    using FlexPlatform.Shared.Validation;

    public class DifferentThan_GenericType<T>
    {
        private string clsErrorMessage;

        protected T clsSpecificValue;

        /// <summary>
        /// Configures the parameter(s) and output message of the rule.
        /// </summary>
        /// <param name="errorMessageFormat"> The localized message in case of error.</param>
        /// <param name="ruleSpecificValue"> The value used by the rule in internal comparisons.</param>
        public void Configure(string errorMessageFormat, T ruleSpecificValue)
        {
            // save the specific value. we will need it in the validation logic.
            clsSpecificValue = ruleSpecificValue;

            // build-up the complete error message.
            // Attention: the provided format might be requiring more parameters, so possibly an exception could be thrown.

            try
            {
                clsErrorMessage = string.Format(errorMessageFormat, ruleSpecificValue);
            }
            catch (Exception ex)
            {
                // if exception has been cought, forward it but encapsulate it in a more explicit exception.
                throw new InvalidOperationException(
                    "Cannot configure the validation rule: specified format for error message is not valid!", ex);
            }
        }

        /// <summary>
        /// Validates the <paramref name="proposedValue"/> against rule's logic and configuration.
        /// </summary>
        /// <param name="proposedValue"> The value proposed.</param>
        /// <returns>A <see cref="ValidationResult"/> object containing details about validation success/fail.</returns>
        public IValidationResult Validate(T proposedValue)
        {
            IValidationResult validationResult = new ValidationResult();

            // Use the extension logic to decide wheter the proposed value is acceptable or not.

            if (!ValueIsOk(proposedValue))
            {
                validationResult.ResultNotification = new Notification();
                validationResult.ResultNotification.NotificationLevel = NotificationLevels.Error;
                validationResult.ResultNotification.Message = clsErrorMessage; 
            }
            
            return validationResult;
        }

        /// <summary>
        /// Evaluates if the proposed value can be accepted in consideration with validation rule specification.
        /// </summary>
        /// <param name="proposedValue"> The proposed value.</param>
        /// <returns> True if value is accepted.</returns>
        protected bool ValueIsOk(T proposedValue)

        {
            if (EqualityComparer<T>.Default.Equals(proposedValue, this.clsSpecificValue))  //(proposedValue == this.clsSpecificValue)
               
            {
                return false;
            }

            else
            {
                return true;
            }
        }

    }
}
